Repository navigation
fix(core): capture pages load only the clips on screen - #7402
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Request changes at 0376faa0. The code looks right to me. Two gate items are blocking.
Blocking
- The body has no
fails without the fix:line. This is a fix PR, so it needs one line naming the test that fails without the fix. The Test plan does describe the failure, but not on the required line. Add, for example:
fails without the fix: packages/core/src/runtime/entry.test.ts › "in a hidden capture page only the clip on screen loads, and the one a seek left is freed"
I checked the claim locally. With onlyinit.tsreverted to the merge-base7ad2be96, that test fails withexpected [ true, true, false ] to deeply equal [ true, false, false ]. At the head it passes, and so does the rest ofentry.test.ts(57/57). - The
Commentsworkflow fails on this head (comment-ratchet, "A package file's comment share may not rise"):packages/core/src/runtime/init.ts: 900 → 901 comment lines. The new// A capture page seeks and never plays…line is the one that tips it.packages/core/src/studioPreviewMark.ts: 0 → 2 comment lines (the JSDoc oncapturePageIn).
Fix: cut them, or move the explanation into the name. For example,capturePageInalready says most of it, and the rule could sit in a named const such asconst loadsAhead = !capturePage.
Checked, no issue
capturePageInmatches the marker read it replaces intimedClipHide.ts(samemeta[name=…]selector andcontent === "capture"). The pages that set the marker are the studio-server preview route andcheckBrowser.- The live preview and the player don't change: every new branch is behind
capturePage. - On a capture page, releasing with
force = trueonly frees a clip that was already decided and has now left the screen, which is what the PR intends.
Non-blocking
- As the body notes,
hyperframes checkhasn't been measured end to end. Now that nothing is prefetched, every check seek onto a new cut starts a cold load. That's worth one timing run on a heavily cut film, to confirm check's wall time doesn't regress where memory improves.
I'll re-review once both blockers are fixed on a new head.
Contributor
Edit accuracy: accurate 267 (base branch 267), smooth 110 of thoseThe gate passes. Quarantined, measured but not gated (8)
Unstable (1)
|
Contributor
There was a problem hiding this comment.
Approve at c6ab3a66. Both blockers from my earlier review are fixed.
fails without the fix:line: it's in the body now and namesentry.test.ts› "in a hidden capture page only the clip on screen loads, and the one a seek left is freed". I checked it again at this head. With onlyinit.tsat the merge-base7ad2be96, the test fails with[true, true, false]vs[true, false, false]. At the head,entry.test.tspasses 57/57.- Comment ratchet: the comments are gone, and the rule now lives in
const loadsAhead = !capturePageIn(document). Between0376faa0and this head the only change is that rename, with logic identical under De Morgan (capturePage→!loadsAhead). TheCommentsworkflow now passes. - CI on this head: all workflows passed (CI, Comments, regression, preview-regression, Windows render, Player perf/Safari perf/Safari audio, CodeQL, PR captures). The cancelled duplicates were superseded by later runs on the same head.
Still non-blocking, as before: one end-to-end hyperframes check timing run on a heavily cut film, to confirm wall time doesn't regress now that nothing is prefetched.
miguel-heygen
enabled auto-merge
November 8, 2026 11:46
This was referenced Nov 8, 2026
Closed
Merged
SanHsien
added a commit
to SanHsien/hyperframes
that referenced
this pull request
Nov 9, 2026
Port the adopted upstream fixes from f5bde95 to the current upstream tip: heygen-com#7375 multipart cloud upload, heygen-com#7382 minParallelChunks, heygen-com#7349 HLG header SEI, heygen-com#7369 skip unmounted compositions in lint/check, heygen-com#7381 filesystem-path media in the cloud archive, heygen-com#7383 Safari cut-point pre-roll revert, heygen-com#7373 clock steering between audio time updates, heygen-com#7384 injector test isolation, heygen-com#7378 preview seek retention, heygen-com#7390 virtual timer schedule per worker, heygen-com#7394 CDN script failure naming, heygen-com#7395 menu row radius, heygen-com#7119 decode timeout caller test, heygen-com#7397 authored tween order, heygen-com#7402 capture page clip loading, heygen-com#7412 muted video audio track at cuts, heygen-com#6150 template root variable test, heygen-com#7442 held tail seek once. Deliberate local differences: heygen-com#7067's audio-start hold is not carried into clock.ts, mountedSources comes from heygen-com#6827 as a helper only, cloud/_gen/types.ts omits the image-request types the fork does not generate, and the lint symlink test skips through symlinkOrSkip where the account cannot create links. Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
SanHsien
added a commit
to SanHsien/hyperframes
that referenced
this pull request
Nov 9, 2026
The 1a9bb89 port of heygen-com#7402 and heygen-com#7378 brought in releaseMedia(el, flag) with window.__HF_RELEASE_PASSED_MEDIA (heygen-com#6929, needs the heygen-com#6785 buffered guard) and registerSeekCompletion(landed, "image-decode") (the SeekHold union from heygen-com#6596). Both upstream commits stay deferred, so typecheck:runtime failed in the Windows render verification workflow. The fork's releaseMedia already frees every clip, so the call keeps its behaviour. Add tsconfig.runtime.json to the pre-commit typecheck, which only covered tsconfig.json (it excludes src/runtime), and pin it in the hook test. Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A capture page (
hf-capture: posters, hover frames, andhyperframes check) now loads only the clips on screen at its seek target. It no longer prefetches upcoming clips or holds clips due at the loop start, and a clip the seek leaves is released even when fully buffered.Why
A capture page seeks and never plays, but it ran the same look-ahead as a playing preview: up to three upcoming clips prefetched, plus clips kept around the playhead. With large footage each hidden capture window held several decoded video streams it never shows. A host that keeps a few capture windows open at once (a poster, a hover window, stills) runs out of renderer memory on long, heavily cut 4K edits.
Measured in a hidden Electron window on a 1080x1920, 30 s composition of 65 cuts taken from six 4K h264 sources, swapping only the runtime script (main at 7ad2be9 vs this branch), after the window settled:
__renderReady)The one video held is the cut on screen at each seek target.
Related work
Refs the capture-mode media rules in
timedClipHide.ts(images were already eager on capture pages; this is the media side).How
capturePageIn(doc)instudioPreviewMark.tsis the one place that reads the capture marker;timedClipHide.tsnow uses it instead of its own copy.init.ts),loadsAheadis false on a capture page, which passesupcoming = falseandforLoop = falsetopreloadNearPlayhead, so only a visible clip is armed, and releases a clip that leaves withreleaseMedia(el, true).Test plan
fails without the fix: packages/core/src/runtime/entry.test.ts › "in a hidden capture page only the clip on screen loads, and the one a seek left is freed" (with only
init.tsat the merge-base it gets[true, true, false]for[true, false, false]).entry.test.ts"in a hidden capture page only the clip on screen loads, and the one a seek left is freed". Fails on main (armed(now, soon, later)is[true, true, false], the upcoming clip loads); passes here. Verified by reverting onlyinit.ts: red.packages/coreruntime suite: 2982 passed, 3 runs in a row; coretsc --noEmit, oxfmt and oxlint clean on the changed files.packages/clicheck tests (check, checkBrowser, checkBrowser.chromium, checkSweep.chromium, publishProxyBake): 265 passed, 4 skipped, as on main.studio-serverpreview route: 153 passed.hyperframes checkmemory end to end on a long composition, and macOS (the window measurement ran on Linux).Size
46 lines on purpose: one rule at the one media-pass call site, the marker read moved to one helper, and its test. Nothing open in this area could carry it.